﻿using System;
using UnityEngine;

namespace RootMotion.FinalIK
{
	// Token: 0x02000045 RID: 69
	[Serializable]
	public class IKSolverFullBody : IKSolver
	{
		// Token: 0x06000317 RID: 791 RVA: 0x00028AC0 File Offset: 0x00026CC0
		public IKEffector GetEffector(Transform t)
		{
			for (int i = 0; i < this.effectors.Length; i++)
			{
				if (this.effectors[i].bone == t)
				{
					return this.effectors[i];
				}
			}
			return null;
		}

		// Token: 0x06000318 RID: 792 RVA: 0x00028B08 File Offset: 0x00026D08
		public FBIKChain GetChain(Transform transform)
		{
			int chainIndex = this.GetChainIndex(transform);
			if (chainIndex == -1)
			{
				return null;
			}
			return this.chain[chainIndex];
		}

		// Token: 0x06000319 RID: 793 RVA: 0x00028B30 File Offset: 0x00026D30
		public int GetChainIndex(Transform transform)
		{
			for (int i = 0; i < this.chain.Length; i++)
			{
				for (int j = 0; j < this.chain[i].nodes.Length; j++)
				{
					if (this.chain[i].nodes[j].transform == transform)
					{
						return i;
					}
				}
			}
			return -1;
		}

		// Token: 0x0600031A RID: 794 RVA: 0x000041BC File Offset: 0x000023BC
		public IKSolver.Node GetNode(int chainIndex, int nodeIndex)
		{
			return this.chain[chainIndex].nodes[nodeIndex];
		}

		// Token: 0x0600031B RID: 795 RVA: 0x000041CD File Offset: 0x000023CD
		public void GetChainAndNodeIndexes(Transform transform, out int chainIndex, out int nodeIndex)
		{
			chainIndex = this.GetChainIndex(transform);
			if (chainIndex == -1)
			{
				nodeIndex = -1;
			}
			else
			{
				nodeIndex = this.chain[chainIndex].GetNodeIndex(transform);
			}
		}

		// Token: 0x0600031C RID: 796 RVA: 0x00028B98 File Offset: 0x00026D98
		public override IKSolver.Point[] GetPoints()
		{
			int num = 0;
			for (int i = 0; i < this.chain.Length; i++)
			{
				num += this.chain[i].nodes.Length;
			}
			IKSolver.Point[] array = new IKSolver.Point[num];
			int num2 = 0;
			for (int j = 0; j < this.chain.Length; j++)
			{
				for (int k = 0; k < this.chain[j].nodes.Length; k++)
				{
					array[num2] = this.chain[j].nodes[k];
				}
			}
			return array;
		}

		// Token: 0x0600031D RID: 797 RVA: 0x00028C34 File Offset: 0x00026E34
		public override IKSolver.Point GetPoint(Transform transform)
		{
			for (int i = 0; i < this.chain.Length; i++)
			{
				for (int j = 0; j < this.chain[i].nodes.Length; j++)
				{
					if (this.chain[i].nodes[j].transform == transform)
					{
						return this.chain[i].nodes[j];
					}
				}
			}
			return null;
		}

		// Token: 0x0600031E RID: 798 RVA: 0x00028CAC File Offset: 0x00026EAC
		public override bool IsValid(ref string message)
		{
			if (this.chain == null)
			{
				message = "FBIK chain is null, can't initiate solver.";
				return false;
			}
			if (this.chain.Length == 0)
			{
				message = "FBIK chain length is 0, can't initiate solver.";
				return false;
			}
			for (int i = 0; i < this.chain.Length; i++)
			{
				if (!this.chain[i].IsValid(ref message))
				{
					return false;
				}
			}
			foreach (IKEffector ikeffector in this.effectors)
			{
				if (!ikeffector.IsValid(this, ref message))
				{
					return false;
				}
			}
			if (!this.spineMapping.IsValid(this, ref message))
			{
				return false;
			}
			foreach (IKMappingLimb ikmappingLimb in this.limbMappings)
			{
				if (!ikmappingLimb.IsValid(this, ref message))
				{
					return false;
				}
			}
			foreach (IKMappingBone ikmappingBone in this.boneMappings)
			{
				if (!ikmappingBone.IsValid(this, ref message))
				{
					return false;
				}
			}
			return true;
		}

		// Token: 0x0600031F RID: 799 RVA: 0x00028DC4 File Offset: 0x00026FC4
		public override void StoreDefaultLocalState()
		{
			this.spineMapping.StoreDefaultLocalState();
			for (int i = 0; i < this.limbMappings.Length; i++)
			{
				this.limbMappings[i].StoreDefaultLocalState();
			}
			for (int j = 0; j < this.boneMappings.Length; j++)
			{
				this.boneMappings[j].StoreDefaultLocalState();
			}
		}

		// Token: 0x06000320 RID: 800 RVA: 0x00028E28 File Offset: 0x00027028
		public override void FixTransforms()
		{
			this.spineMapping.FixTransforms();
			for (int i = 0; i < this.limbMappings.Length; i++)
			{
				this.limbMappings[i].FixTransforms();
			}
			for (int j = 0; j < this.boneMappings.Length; j++)
			{
				this.boneMappings[j].FixTransforms();
			}
		}

		// Token: 0x06000321 RID: 801 RVA: 0x00028E8C File Offset: 0x0002708C
		public override void OnInitiate()
		{
			for (int i = 0; i < this.chain.Length; i++)
			{
				this.chain[i].Initiate(this);
			}
			foreach (IKEffector ikeffector in this.effectors)
			{
				ikeffector.Initiate(this);
			}
			this.spineMapping.Initiate(this);
			foreach (IKMappingBone ikmappingBone in this.boneMappings)
			{
				ikmappingBone.Initiate(this);
			}
			foreach (IKMappingLimb ikmappingLimb in this.limbMappings)
			{
				ikmappingLimb.Initiate(this);
			}
		}

		// Token: 0x06000322 RID: 802 RVA: 0x00028F54 File Offset: 0x00027154
		public override void OnUpdate()
		{
			if (this.IKPositionWeight <= 0f)
			{
				for (int i = 0; i < this.effectors.Length; i++)
				{
					this.effectors[i].positionOffset = Vector3.zero;
				}
				return;
			}
			if (this.chain.Length == 0)
			{
				return;
			}
			this.IKPositionWeight = Mathf.Clamp(this.IKPositionWeight, 0f, 1f);
			if (this.OnPreRead != null)
			{
				this.OnPreRead();
			}
			this.ReadPose();
			if (this.OnPreSolve != null)
			{
				this.OnPreSolve();
			}
			this.Solve();
			if (this.OnPostSolve != null)
			{
				this.OnPostSolve();
			}
			this.WritePose();
			for (int j = 0; j < this.effectors.Length; j++)
			{
				this.effectors[j].OnPostWrite();
			}
		}

		// Token: 0x06000323 RID: 803 RVA: 0x00029040 File Offset: 0x00027240
		public virtual void ReadPose()
		{
			for (int i = 0; i < this.chain.Length; i++)
			{
				if (this.chain[i].bendConstraint.initiated)
				{
					this.chain[i].bendConstraint.LimitBend(this.IKPositionWeight, this.GetEffector(this.chain[i].nodes[2].transform).positionWeight);
				}
			}
			for (int j = 0; j < this.effectors.Length; j++)
			{
				this.effectors[j].ResetOffset(this);
			}
			for (int k = 0; k < this.effectors.Length; k++)
			{
				this.effectors[k].OnPreSolve(this);
			}
			for (int l = 0; l < this.chain.Length; l++)
			{
				this.chain[l].ReadPose(this, this.iterations > 0);
			}
			if (this.iterations > 0)
			{
				this.spineMapping.ReadPose();
				for (int m = 0; m < this.boneMappings.Length; m++)
				{
					this.boneMappings[m].ReadPose();
				}
			}
			for (int n = 0; n < this.limbMappings.Length; n++)
			{
				this.limbMappings[n].ReadPose();
			}
		}

		// Token: 0x06000324 RID: 804 RVA: 0x000291A0 File Offset: 0x000273A0
		public virtual void Solve()
		{
			if (this.iterations > 0)
			{
				for (int i = 0; i < this.iterations; i++)
				{
					if (this.OnPreIteration != null)
					{
						this.OnPreIteration(i);
					}
					for (int j = 0; j < this.effectors.Length; j++)
					{
						if (this.effectors[j].isEndEffector)
						{
							this.effectors[j].Update(this);
						}
					}
					this.chain[0].Push(this);
					this.chain[0].Reach(this);
					for (int k = 0; k < this.effectors.Length; k++)
					{
						if (!this.effectors[k].isEndEffector)
						{
							this.effectors[k].Update(this);
						}
					}
					this.chain[0].SolveTrigonometric(this, false);
					this.chain[0].Stage1(this);
					for (int l = 0; l < this.effectors.Length; l++)
					{
						if (!this.effectors[l].isEndEffector)
						{
							this.effectors[l].Update(this);
						}
					}
					this.chain[0].Stage2(this, this.chain[0].nodes[0].solverPosition);
					if (this.OnPostIteration != null)
					{
						this.OnPostIteration(i);
					}
				}
			}
			if (this.OnPreBend != null)
			{
				this.OnPreBend();
			}
			for (int m = 0; m < this.effectors.Length; m++)
			{
				if (this.effectors[m].isEndEffector)
				{
					this.effectors[m].Update(this);
				}
			}
			this.ApplyBendConstraints();
		}

		// Token: 0x06000325 RID: 805 RVA: 0x000041F9 File Offset: 0x000023F9
		public virtual void ApplyBendConstraints()
		{
			this.chain[0].SolveTrigonometric(this, true);
		}

		// Token: 0x06000326 RID: 806 RVA: 0x00029360 File Offset: 0x00027560
		public virtual void WritePose()
		{
			if (this.IKPositionWeight <= 0f)
			{
				return;
			}
			if (this.iterations > 0)
			{
				this.spineMapping.WritePose(this);
				for (int i = 0; i < this.boneMappings.Length; i++)
				{
					this.boneMappings[i].WritePose(this.IKPositionWeight);
				}
			}
			for (int j = 0; j < this.limbMappings.Length; j++)
			{
				this.limbMappings[j].WritePose(this, this.iterations > 0);
			}
		}

		// Token: 0x04000203 RID: 515
		[Range(0f, 10f)]
		public int iterations = 4;

		// Token: 0x04000204 RID: 516
		public FBIKChain[] chain = new FBIKChain[0];

		// Token: 0x04000205 RID: 517
		public IKEffector[] effectors = new IKEffector[0];

		// Token: 0x04000206 RID: 518
		public IKMappingSpine spineMapping = new IKMappingSpine();

		// Token: 0x04000207 RID: 519
		public IKMappingBone[] boneMappings = new IKMappingBone[0];

		// Token: 0x04000208 RID: 520
		public IKMappingLimb[] limbMappings = new IKMappingLimb[0];

		// Token: 0x04000209 RID: 521
		public IKSolver.UpdateDelegate OnPreRead;

		// Token: 0x0400020A RID: 522
		public IKSolver.UpdateDelegate OnPreSolve;

		// Token: 0x0400020B RID: 523
		public IKSolver.IterationDelegate OnPreIteration;

		// Token: 0x0400020C RID: 524
		public IKSolver.IterationDelegate OnPostIteration;

		// Token: 0x0400020D RID: 525
		public IKSolver.UpdateDelegate OnPreBend;

		// Token: 0x0400020E RID: 526
		public IKSolver.UpdateDelegate OnPostSolve;
	}
}
